import { Service } from 'egg';
import * as Jsapi from 'wechat_interaction_jsapi';
import * as fs from 'fs';
import * as request from 'request';
import * as path from 'path';
import * as resizeImg from 'resize-img';
import * as ffmpeg from 'fluent-ffmpeg';
import * as moment from 'moment';
import * as ejsExcel from 'ejsexcel';

export default class UploadService extends Service {
    /**
     * 从微信服务器下载文件
     * @param param 
     */
    public async uploadImage(param: any) {
        try {
            const type = param.type;
            const _this = this;
            //保存图片或语音url
            let imgName = '';
            let url = '';
            if (!type || type == 1) {
                imgName = this.ctx.helper.genImgName() + '.jpg';
                url = path.join(__dirname, '../public/img/', imgName);
            } else if (type == 2) {
                imgName = this.ctx.helper.genImgName() + '.amr';
                url = path.join(__dirname, '../public/amr/', imgName);
            } else {
                throw new Error(JSON.stringify({ code: 2, msg: '无法识别的类型' }));
            }
            const { weixin } = this.app.config;
            const jssdk = new Jsapi(weixin.appId, weixin.appSecret);
            const uploadUrl = `https://api.weixin.qq.com/cgi-bin/media/get?access_token=${await jssdk.getAccessToken()}&media_id=${param.serverId}`;
            //获取文件并保存
            const result: any = request({
                method: 'GET',
                url: uploadUrl
            });
            result.pipe(fs.createWriteStream(url));
            let result2: any = await new Promise((resolve) => {
                result.on("end", function () {
                    // 查看上传的是否是图片
                    let res = fs.readFileSync(url, 'utf-8');
                    if (String(res).length < 200) {
                        _this.ctx.logger.error(String(res));
                        try {
                            fs.unlinkSync(url);
                        } catch (e) {
                            _this.ctx.logger.error(e);
                        }
                        resolve({ code: 2, msg: '上传失败,请重新上传' });
                    } else {
                        if (!type || type == 1) {
                            resizeImg(fs.readFileSync(url), { width: 200 }).then(buf => {
                                const newUrl = path.join(__dirname, '../public/img/', 'THUM-' + imgName);
                                fs.writeFileSync(newUrl, buf);
                                resolve({ code: 1, msg: '上传图片成功', data: { url: imgName } });
                            }).catch(e => {
                                resolve({ code: 2, msg: '上传失败,请重新上传' + e });
                            })
                        } else {
                            const uuid = imgName.split('.')[0];
                            const mp3name = uuid + '.mp3';
                            const targetUrl = path.join(__dirname, '../public/amr/', mp3name);
                            ffmpeg(url)
                                .format('mp3')
                                .on('end', function () {
                                    fs.unlinkSync(url);
                                    resolve({ code: 1, msg: '上传成功', data: { url: mp3name } });
                                })
                                .on('error', function (err) {
                                    resolve({ code: 2, msg: '上传失败,请重新上传' + err.message });
                                })
                                .save(targetUrl);
                        }
                    }
                });
                result.on("error", function () {
                    resolve({ code: 2, msg: '上传失败' });
                });
            });
            if (result2.code === 1) {
                return { url: result2.data.url };
            } else {
                throw new Error(JSON.stringify({ code: 2, msg: result2.msg }));
            }
        } catch (e) {
            throw new Error(JSON.stringify({ code: 2, msg: '上传失败' + e.message }));
        }
    }

    /**
     * 导出excel报名表
     * @param param 
     */
    public async exportExcel(param: any) {
        try {
            const { activity_id } = param;
            const queryStr = `
                    SELECT
                        u.user_nickname,
                        u.user_student_id,
                        c.college_name
                    FROM
                        t_activity_enroll a
                        INNER JOIN t_user u ON a.user_id = u.user_id 
                        AND u.is_delete = '1'
                        INNER JOIN t_school s ON u.user_school_id = s.school_id 
                        AND s.school_status = '1'
                        INNER JOIN t_college c ON u.user_college_id = c.college_id 
                        AND c.college_status = '1' 
                    WHERE
                        a.activity_enroll_status = '1' 
                        AND a.is_delete = '1' 
                        AND a.activity_id = :activity_id`;
            const result: any = await this.ctx.model.query(queryStr, {
                type: this.ctx.model.QueryTypes.SELECT,
                replacements: { activity_id }
            });
            const list: any = [];
            for (let i = 0; i < result.length; i++) {
                const item: any = {};
                item.student_id = result[i].user_student_id;
                item.user_name = result[i].user_nickname;
                item.college_name = result[i].college_name;
                item.work_start_time = '';
                item.work_end_time = '';
                item.work_status = '';
                item.leave_status = '';
                item.late_status = '';
                list.push(item);
            }
            let resultList: any = [];
            resultList.push(list);
            const exlBuf = fs.readFileSync(path.join(__dirname, '../public/', 'activityEnrollList.xlsx'));
            const now = moment().format('YYYYMMDDHHmmss');
            const excelData = await new Promise((resolve, reject) => {
                ejsExcel.renderExcelCb(exlBuf, resultList, function (err, exlBuf2) {
                    if (err) {
                        reject(err);
                    }
                    resolve(exlBuf2);
                })
            })
            return { name: "报名表-" + now + '.xlsx', data: excelData };
        } catch (e) {
            throw new Error(JSON.stringify({ code: 3, msg: e.message }));
        }
    }
}